<!DOCTYPE html>
<!--
     SPDX-License-Identifier: CC-BY-SA-4.0
     SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC.
-->
<!-- Page last generated 2025-02-20 03:16:15 +0000 -->
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Using CAN on L4T through an MCP251X | seL4 docs</title>

    <!-- Our stylesheet and theme stylesheet.  Contains bootstrap. -->
    <link rel="stylesheet" href="/assets/css/style.css" type="text/css">
    <!-- Font awesome -->
    <link href="https://use.fontawesome.com/releases/v5.0.8/css/all.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
    <!-- Pygments syntax highlighting  -->
    <link rel="stylesheet" href="/assets/css/highlighting/trac.css" type="text/css">
    <link rel="icon" type="image/x-icon" href="/assets/favicon.ico"><script defer data-domain="docs.sel4.systems"
	    src="https://analytics.sel4.systems/js/script.js"></script></head>

  <body class="container-fluid">

    



<header>
  <ul class="row menu">
    <li class="col-xs-12 col-md-2" >
            <a href="https://sel4.systems" class="skip-icon">
              <img class="img-responsive" src="/assets/logo-text-white.svg" alt="seL4 logo" />
            </a>
    </li>
    <li class="col-xs-12 col-md-10 menu">
      <nav aria-label="Banner links">
        <h2><a href="/Resources" />Resources</h2>
        <h2><a href="/processes" />Contributing</a></h2>
        <h2><a href="/projects" />Projects</h2>
        <h2><a href="/Tutorials" />Tutorials</h2>
        <iframe title="DuckDuckGo search bar" src="https://duckduckgo.com/search.html?site=docs.sel4.systems&prefill=Search%20sel4.systems" style="overflow:hidden;margin-bottom:10px; padding:0;height:40px;float:right;border-width: 0px"></iframe>
      </nav>
    </li>
  </ul>
  <div class="clear"></div>
  
<div class="breadcrumbs bootstrap hidden-sm-down">
  <nav class="sel-breadcrumb" aria-label="Breadcrumb" >
    <ol class=" list-unstyled" vocab="http://schema.org/" typeof="BreadcrumbList">
      
      
        

        

        <li class="breadcrumb-item" property="itemListElement" typeof="ListItem">
            <a property="item" typeof="WebPage" href="/">
              <span property="name"><b>seL4 Docs</b></span>
            </a>
            <meta property="position" content="1" />
        </li>
      
        

        

        <li class="breadcrumb-item" property="itemListElement" typeof="ListItem">
            <a property="item" typeof="WebPage" href="/Hardware/">
              <span property="name"><b>Supported platforms</b></span>
            </a>
            <meta property="position" content="2" />
        </li>
      
        

        

        <li class="breadcrumb-item" property="itemListElement" typeof="ListItem">
            <a property="item" typeof="WebPage" href="/Hardware/CEI_TK1_SOM/">
              <span property="name"><b>TK1 som</b></span>
            </a>
            <meta property="position" content="3" />
        </li>
      
        

        
          <li class="breadcrumb-item" property="itemListElement" typeof="ListItem">
            <span property="name">Using CAN on L4T through an MCP251X</span>
            <meta property="position" content="4" /></li>
          
    </ol>
  </nav>
  <nav class="sel-version" aria-label="Current Versions">
    <ol class="list-unstyled">
      <li class="list-unstyled text-right" style="margin-left:auto; padding:0rem 0rem;">
        Current versions:</li>
      <li class="list-unstyled text-right">
      <a href="/releases/sel4/13.0.0"><b>seL4-13.0.0</b></a></li>
      <li class="list-unstyled text-right">
      <a href="/releases/microkit/1.4.1"><b>microkit-1.4.1</b></a></li>
      <li class="list-unstyled text-right">
      <a href="/releases/camkes/camkes-3.11.0"><b>camkes-3.11.0</b></a></li>
      <li class="list-unstyled text-right">
      <a href="/releases/capdl/0.3.0"><b>capDL-0.3.0</b></a></li>
      </ol>
  </nav>
  <div class='clear'></div>
</div>


</header>

    <main>
      <div class="row">
  <div class="hidden-xs col-sm-4 col-md-3 col-lg-2">
    


<div class="sidebar">
















</div>

  </div>
  <div class="col-sm-8 col-md-9 col-lg-8 main">
    
    <div class="content">
      <h1 id="using-can-on-l4t-through-an-mcp251x">Using CAN on L4T through an MCP251X</h1>

<p><img style="width: 25%" src="front.jpg" alt="Front view of TK1-Tower" />
<img style="width: 25%" src="bottom.jpg" alt="Bottom view of TK1-Tower" /></p>

<h2 id="before-running-l4tcan-jumper-hw-based-chipselect-to-the-gpio-chipselect">Before running L4TCAN: Jumper HW-based chipselect to the GPIO chipselect</h2>
<p>Because L4T with CAN doesn’t use GPIO chipselect (yet),
it’s necessary to connect the hardware CSN line to the GPIO used for
chipselect.</p>

<p>Note that the GPIO dts sets the GPIO used for chipselect to high
impedance so bad things don’t happen.</p>

<p>CSN is indicated on the SPI expansion header. Can node #1 on the CAN
daughterboard uses TK1_GPIO2, so it’s necessary to connect these 2
pins:</p>

<p><img style="width: 60%" src="jumper.jpg" alt="Jumper hw-based chipselect to GPIO chipselect" /></p>

<p>(From right-to-left on the TK1 GPIO header we have GPIO0, GPIO1, GPIO2)</p>

<p>NOTE: On the seL4 side, this may not be necessary as it will be able to
use GPIO-based chipselects.</p>

<p>NOTE2: Justification for GPIO chipselects is that we have 2 CAN nodes
and only 1 HW chipselect, so had to do it this way.</p>

<h2 id="option-1-use-our-linux-image">Option 1. Use our Linux image</h2>
<p>Grab the image at <a href="https://trustworthy.systems/Downloads/tk1_can/tk1_can.img.gz">tk1_can.img.gz</a> (<a href="https://trustworthy.systems/Downloads/tk1_can/checksum.txt">md5</a>). Make sure to verify against the
md5sum in the same folder once you’ve got it.</p>

<p>Set up the TK1 as usual - connect the UART as well as the recovery USB
port next to the ethernet jack. Stop u-boot from booting and issue the
command:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ums 0 mmc 0
</code></pre></div></div>
<p>This will allow you to see the TK1’s filesystem on
your host pc. On your host PC, list your devices:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ lsblk
</code></pre></div></div>
<p>You should see a 14.7GB-ish device with a few
partitions - this is the TK1. (Make sure it is by mounting the largest
partition and looking at the rootfs [making sure to unmount again
before next step!])</p>

<p>We’re ready to image the TK1. Issue the following command, making
ABSOLUTELY sure that your of=/dev/sdX line is correct so you don’t
accidentally destroy data on your machine. Also, you want /dev/sdX (the
device), NOT /dev/sdX3 (partitions) etc.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gunzip -c tk1_can.img.gz | sudo dd of=/dev/&lt;your TK1 device&gt; conv=sync bs=4K status=progress
</code></pre></div></div>
<p>This takes ~1.5Hr on my machine to
complete. If dd throws a strange error to do with the ‘status=progress’
command, you may be using an old version of dd, it’s fine to omit this
command however you will not see a progress bar.</p>

<p>Once this is complete, exit the ums command in u-boot and attempt to
boot. As long as the can board CS is jumpered to GPIO2, everything
should work.</p>

<p>You may see some lines after boot like:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rt5639 0-001c: Failed to set private addr: -121
</code></pre></div></div>

<p>This is normal,
and everything should work regardless (internet connectivity works fine
on our system). We’ll be looking into the reason for these errors in the
future.</p>

<p>See bottom of this page for ‘hello-world’-type examples.</p>

<h2 id="option-2-compile-your-own-linux">Option 2: compile your own Linux</h2>
<p>The instructions from here on go
from a vanilla TK1-SOM L4T configuration to one which can support CAN
using the daughterboard.</p>

<p>Getting native Linux CAN drivers to work on the TK1-SOM requires a bit
of hackery, procedure outlined here.</p>

<p>Before going ahead with this, follow the TK1-SOM custom kernel
procedure, make sure you can build it and flash to the board</p>

<h3 id="add-device-tree-support-for-mcp251x-to-l4t--perform-driver-hacks">Add device tree support for MCP251X to L4T &amp; perform driver hacks</h3>
<p>The kernel that is included in L4T does not support device tree
binding for the mcp251X, so you have to modify the kernel driver.</p>

<p>Easiest way to do that is to just use mine: (Works with latest L4T from
colorado. Don’t use the upstream NVIDIA L4T)</p>

<p>Get it here: <a href="/Hardware/CEI_TK1_SOM/L4TCan/mcp251x.c">mcp251x.c</a></p>

<p>You want to replace the file in drivers/net/can/mcp251x.c</p>

<p>NOTE: this is NOT the same as the file in mainline kernel, it has a hack
that fixes a problem I had with the device tree not recognising clock
nodes.</p>

<p>This means that this file will only work with an MCP251X that has a
20MHz crystal!</p>

<p>I’ve also added a lot of debugging information to the driver so that
dmesg is a bit more helpful.</p>

<h3 id="look-at-device-tree-documentation">Look at device tree documentation</h3>
<p>Device tree documentation does
not exist in the source code as mcp support has been hacked in. Here’s
the docs from mainline:</p>

<p>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
-   Microchip MCP251X stand-alone CAN controller device tree bindings

Required properties:

- compatible: Should be one of the following:
      -   "microchip,mcp2510" for MCP2510.

      - "microchip,mcp2515" for MCP2515.
- reg: SPI chip select.
- clocks: The clock feeding the CAN controller.
- interrupt-parent: The parent interrupt controller.
- interrupts: Should contain IRQ line for the CAN controller.

Optional properties:

- vdd-supply: Regulator that powers the CAN controller.
- xceiver-supply: Regulator that powers the CAN transceiver.

Example:

  can0: &lt;can@1&gt; {

      compatible = "microchip,mcp2515";
      reg = &lt;1&gt;;
      clocks = &lt;&amp;clk24m&gt;;
      interrupt-parent = &lt;&amp;gpio4&gt;;
      interrupts = &lt;13 0x2&gt;;
      vdd-supply = &lt;&amp;reg5v0&gt;;
      xceiver-supply = &lt;&amp;reg5v0&gt;;
  };
</code></pre></div></div>

<h3 id="modify-the-device-tree">Modify the device tree</h3>
<p>Replace the existing .dts files with
<a href="/Hardware/CEI_TK1_SOM/L4TCan/tegra124-tk1-som-pm375-000-c00-00.dts">tegra124-tk1-som-pm375-000-c00-00.dts</a></p>

<p>You also need to remap some GPIOs, swap out the GPIO device tree with
<a href="/Hardware/CEI_TK1_SOM/L4TCan/tegra124-tk1-som-gpio-default.dtsi">tegra124-tk1-som-gpio-default.dtsi</a></p>

<h3 id="kernel-build-configuration">Kernel Build Configuration</h3>
<p>Using make menuconfig, enable CAN and
MCP251X modules. Make sure your .config contains:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CONFIG_CAN=m
CONFIG_CAN_RAW=m
CONFIG_CAN_BCM=m
CONFIG_CAN_GW=m
CONFIG_CAN_VCAN=m
CONFIG_CAN_DEV=m
CONFIG_CAN_CALC_BITTIMING=y
CONFIG_CAN_MCP251X=m
</code></pre></div></div>
<p>In addition to
the ‘normal’ tk1-som kernel build settings given by Colorado in their
readme.</p>

<p>It is up to you whether you would like to leave user-mode SPI drivers in
there or not, they simply won’t load as the CAN dts removes the
user-space SPI device.</p>

<p>Once we figure out how to do GPIO-muxed chipselect on the TK1SOM
(working on it) it will be possible to use more than one CAN node &amp;
user-space SPI at the same time.</p>

<h3 id="enable-hardware-based-chipselect-0">Enable hardware-based chipselect #0</h3>
<p>There is a strange old
touch-driver hanging around that needs to be disabled for you to be able
to use hardware CS on the TK1-SOM’s SPI line.</p>

<p>Originally I pulled it out of the TK1-SOM’s SPI driver, but it turns out
you can disable it in extlinux.conf, which is much simpler.</p>

<p>in /boot/extlinux/extlinux.conf on your rootfs, find the touch_id=0@0
line, and change it to touch_id=3@3</p>

<h3 id="load-everything-onto-the-board">Load everything onto the board</h3>
<p>You could do something like this:</p>

<p>update_kernel.sh</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="nv">L4T_DIR</span><span class="o">=</span>/home/seb/TK1_SOM_2GB_Flashing/Linux_for_Tegra
<span class="nv">SOM_DIR</span><span class="o">=</span>/mnt/TK1SOM

<span class="nb">sudo cp</span> <span class="nv">$L4T_DIR</span>/sources/kernel/arch/arm/boot/zImage
<span class="nv">$SOM_DIR</span>/boot/zImage <span class="nb">sudo cp</span>
<span class="nv">$L4T_DIR</span>/sources/kernel/arch/arm/boot/dts/tegra124-tk1-som-pm375-000-c00-00.dtb
<span class="nv">$SOM_DIR</span>/boot/tegra124-tk1-som-pm375-000-c00-00.dtb
</code></pre></div></div>

<p>rebuild.sh - assumes u-boot running <code class="language-plaintext highlighter-rouge">umc 0 mmc 0</code> at <code class="language-plaintext highlighter-rouge">&lt;tk1&gt;</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    make

    make modules

    mount /dev/&lt;tk1&gt; /mnt/TK1SOM

    ./update_kernel.sh

    make modules_install INSTALL_MOD_PATH=/mnt/TK1SOM

    umount /dev/sdb1
</code></pre></div></div>

<h1 id="hello-world">Hello, world</h1>

<p>When you boot up Linux login as: ubuntu password ubuntu.</p>

<p>Then:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dmesg | grep mcp # See if the driver loaded properly

[ 618.718288] mcp251x spi0.0: entered mcp251x_can_probe
[ 618.718296] mcp251x spi0.0: v2
[ 618.718332] mcp251x spi0.0: got clock
[ 618.718336] mcp251x spi0.0: finished clock configuration, freq: 20000000
[ 618.718353] mcp251x spi0.0: allocated CAN device
[ 618.718358] mcp251x spi0.0: clock prepared for enable
[ 618.729737] mcp251x spi0.0: configured can netdev
[ 618.729741] mcp251x spi0.0: power &amp; transceiver regulator pointers OK
[ 618.729745] mcp251x spi0.0: enabled power
[ 618.729749] mcp251x spi0.0: about to enable DMA (if required)
[ 618.729754] mcp251x spi0.0: finished allocating DMA &amp; non-DMA buffers
[ 618.729757] mcp251x spi0.0: netdev set
[ 618.729799] mcp251x spi0.0: configured SPI bus
[ 618.740194] mcp251x spi0.0: CANSTAT 0x80 CANCTRL 0x07
[ 618.740198] mcp251x spi0.0: successful hardware probe
[ 618.740795] mcp251x spi0.0: probed
[ 628.973815] mcp251x spi0.0: CNF: 0x00 0xbf 0x02

ls /sys/class/net # See if the can device is available and what it's called
can0 dummy0 eth0 ip6tnl0 lo rmnetctl sit0

sudo ip link set can0 up type can bitrate 500000 # Bring it up
ifconfig                                         # Take a look...
can0      Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          UP RUNNING NOARP MTU:16 Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10{
          RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

eth0      Link encap:Ethernet HWaddr 00:50:c2:72:00:59
          inet addr:10.13.1.223 Bcast:10.13.1.255 Mask:255.255.254.0
          inet6 addr: 2402:1800:4000:1:250:c2ff:fe72:59/64 Scope:Global
          inet6 addr: fe80::250:c2ff:fe72:59/64 Scope:Link
------------------------------------------------------------------------

sudo apt-get install can-utils # (make sure to enable universe repository &amp; update)
cansend can0 5A1#11.22.33.44.55.66.77.88 # Send a packet
candump can0 # Dump packets
</code></pre></div></div>

<h1 id="loopback-mode-test">Loopback mode test</h1>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ip link set can0 type can bitrate 500000 loopback on
ifconfig can0 up
candump any,0:0,#FFFFFFFF #In terminal 1
cansend can0 123#dead     #In terminal 2
</code></pre></div></div>

    </div>
  </div>
</div>

    </main>
    


<footer class="site-footer">

  <h2 class="footer-heading">seL4 docs</h2>

  <div class="footer-col-wrapper">

    <div class="col-md-2">
      



<ul class="social-media-list">
  <li><a href="https://github.com/sel4"><i class="fab fa-github"></i> <span class="username">sel4</span></a></li><li><a href="https://github.com/sel4proj"><i class="fab fa-github"></i> <span class="username">sel4proj</span></a></li>
</ul>

    </div>

    <div class="col-md-8">
      <ul class="list-unstyled">
        <li>
          This site is for displaying seL4 related documentation.  Pull requests are welcome.
        </li>
        
          <li>
            Site last updated: Fri Feb 7 10:17:38 2025 +1100 ee78c8857c
          </li>
          <li>
                Page last updated: Wed Aug 25 12:10:59 2021 +1000 c6060204d6
          </li>
        
      </ul>
    </div>
    <div class="col-md-2">
<a href="https://github.com/seL4/docs/blob/master/Hardware/CEI_TK1_SOM/L4TCan/index.md">View page on GitHub</a>
      <br />
      <a href="https://github.com/seL4/docs/edit/master/Hardware/CEI_TK1_SOM/L4TCan/index.md">Edit page on GitHub</a>
      <br />
      <a href="/sitemap">Sitemap</a>
    </div>

  </div>

</footer>

  </body>
</html>
